package com.mgee.netty.server.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import com.alibaba.fastjson.JSON;
import com.google.protobuf.InvalidProtocolBufferException;
import com.mgee.netty.server.pojo.NewChatUserInfo;
import com.mgee.netty.server.protobuf.ImProto;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.protobuf.Any;
import com.mgee.netty.server.constant.MessagingConst;
import com.mgee.netty.server.netty.IoSession;
import com.mgee.netty.server.netty.SessionManager;
import com.mgee.netty.server.pojo.ChatUserInfo;
import com.mgee.netty.server.pojo.LobbyRoomInfo;
import com.mgee.netty.server.protobuf.ImProto.AddPlayer;
import com.mgee.netty.server.protobuf.ImProto.ExitRoom;
import com.mgee.netty.server.protobuf.ImProto.GameCommand;
import com.mgee.netty.server.protobuf.ImProto.GameCommandType;
import com.mgee.netty.server.protobuf.ImProto.ImMsg;
import com.mgee.netty.server.protobuf.ImProto.JoinRoomRequest;
import com.mgee.netty.server.protobuf.ImProto.JoinRoomResponse;
import com.mgee.netty.server.protobuf.ImProto.PlayerPack;
import com.mgee.netty.server.protobuf.ImProto.UpPos;
import com.mgee.netty.server.protobuf.ImProto.UpPosResponse;
import com.mgee.netty.server.util.JacksonUtil;
import com.mgee.netty.server.util.MessageBuilder;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author mileswan
 *
 */
@Service
@Slf4j
public class RoomService {
	
	@Autowired
	private SessionManager sessionManager;

	public String ROOM_NO = "chimeta_card";
	
	public void updateMaxUsers(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			//String sender_uid = currSession.getUser().getUid();
			GameCommand gameCommand = imMsg.getMsg().unpack(GameCommand.class);
			if(gameCommand.getType() != GameCommandType.Update_Room_Maxusers) {
				return;
			}
			
			String content = gameCommand.getContent();
			MessagingConst.globalParams.put(MessagingConst.PARAMKEY_ROOM_MAXUSERS, content);
			
	    	// 按照定义的数据结构，创建登录返回消息对象  
			ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, "Operation Success");
	        //发送反馈消息
	        currSession.sendMessage(responseMsg);
	        
		}catch(Exception e) {
			log.error("updateMaxUsers时发生异常, ", e);
		}
		
		
	}
	
	public void syncUsers(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			GameCommand gameCommand = imMsg.getMsg().unpack(GameCommand.class);
			if(gameCommand.getType() != GameCommandType.Sync_Room_User_Status) {
				return;
			}
			
			sessionManager.sendMessageToRoomUsers(imMsg, sender_uid);
			
	    	// 按照定义的数据结构，创建登录返回消息对象  
			ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, "Operation Success");
	        //发送反馈消息
	        currSession.sendMessage(responseMsg);
	        
		}catch(Exception e) {
			log.error("updateMaxUsers时发生异常, ", e);
		}
		
		
	}
	
	
	public void listRoom(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			List<String> roomIdList = new ArrayList<String>();
			if(SessionManager.groupId2Users != null) {
				for(Map.Entry<String, Map<String, ChatUserInfo>> entry : SessionManager.groupId2Users.entrySet()) {
					roomIdList.add(entry.getKey());
				}
			}
	    	// 按照定义的数据结构，创建登录返回消息对象  
			ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, JacksonUtil.ObjectToString(roomIdList));
	        //发送反馈消息
	        currSession.sendMessage(responseMsg);
	        
		}catch(Exception e) {
			log.error("List Room时发生异常, ", e);
		}
		
	}

	/**
	 * 加入房间
	 * @param imMsg
	 * @param currSession
	 */
	public void newJoinRoom(ImProto.ImMsg imMsg, IoSession currSession) {
		log.info("RoomService newJoinRoom doing~");
		try {
			ImProto.CloudCubeBroadcast cloudCubeBroadcast = imMsg.getMsg().unpack(ImProto.CloudCubeBroadcast.class);
			NewChatUserInfo newChatUserInfo = currSession.getNewChatUserInfo();
			if (Objects.isNull(newChatUserInfo) || StringUtils.isBlank(newChatUserInfo.getUid())){
				log.error("RoomService newJoinRoom error newChatUserInfo is:{}", JSON.toJSONString(newChatUserInfo));
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "cube无法找到用户信息!"));
				return;
			}
			String senderUid = newChatUserInfo.getUid();
			String username = newChatUserInfo.getUsername();
//			String roomNo = cloudCubeBroadcast.getRoomNo();
			String roomNo = "chimeta";
			Map<String, NewChatUserInfo> roomUserMap = SessionManager.newGroupId2Users.get(roomNo);
			if(roomUserMap == null) {
				roomUserMap = new ConcurrentHashMap<String, NewChatUserInfo>();
			}
//			else if(roomUserMap.get(senderUid) != null) {
//				log.error("RoomService newJoinRoom error user is in room chatUserInfo is:{}", JSON.toJSONString(newChatUserInfo));
//				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户已在房间中!"));
//				return;
//			}

			roomUserMap.put(senderUid, newChatUserInfo);

			SessionManager.newGroupId2Users.put(roomNo, roomUserMap);
			SessionManager.userId2GroupIds.put(senderUid, roomNo);
			log.info("RoomService newJoinRoom roomNo:{}, senderUid:{}", roomNo, senderUid);
			//广播加入房间消息
			if(StringUtils.isNotBlank(roomNo) && StringUtils.isNotBlank(senderUid)) {

				ImProto.AddPlayerPack.Builder addPlayerPack = ImProto.AddPlayerPack.newBuilder();
				addPlayerPack.setUsername(username);
				addPlayerPack.setUid(senderUid);

				ImProto.ImMsg.Builder imMsgBuilder = ImProto.ImMsg.newBuilder();
				imMsgBuilder.setMsg(Any.pack(addPlayerPack.build()));
				imMsgBuilder.setId(imMsg.getId());

				log.info("RoomService newJoinRoom send start");
				sessionManager.sendMessageToRoomUsers(imMsgBuilder.build(), senderUid);
			}
			// 按照定义的数据结构，创建返回消息对象
			ImProto.AllRoomPlayerResponse.Builder allRoomPlayerResponseBuilder = ImProto.AllRoomPlayerResponse.newBuilder();

			log.info("1111111");
			for(NewChatUserInfo roomUser : SessionManager.newGroupId2Users.get(roomNo).values()) {
				if(roomUser.getUid() == null) continue;
				ImProto.UserInfoPack.Builder userInfoPackBuilder = ImProto.UserInfoPack.newBuilder();
				userInfoPackBuilder.setUid(roomUser.getUid());
				userInfoPackBuilder.setUsername(roomUser.getUsername());

				allRoomPlayerResponseBuilder.addUserInfoPack(userInfoPackBuilder);
			}
			log.info("2222222");

			ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
			imMsgBuilder.setMsg(Any.pack(allRoomPlayerResponseBuilder.build()));
			imMsgBuilder.setId(imMsg.getId());
			log.info("3333333");

			//发送反馈消息
			currSession.sendMessage(imMsgBuilder.build());
			log.info("444444");

		}catch(Exception e) {
			log.error("RoomService newJoinRoom error:", e);
			currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户进入房间失败!"));
		}
	}

	/**
	 * 加入房间
	 * @param imMsg
	 * @param currSession
	 */
	public void newJoinCardRoom(ImProto.ImMsg imMsg, IoSession currSession) {
		log.info("RoomService newJoinCardRoom doing~");
		try {
			NewChatUserInfo newChatUserInfo = currSession.getNewChatUserInfo();
			if (Objects.isNull(newChatUserInfo) || StringUtils.isBlank(newChatUserInfo.getUid())){
				log.error("RoomService newJoinCardRoom error newChatUserInfo is:{}", JSON.toJSONString(newChatUserInfo));
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "cardJoin无法找到用户信息!"));
				return;
			}
			String senderUid = newChatUserInfo.getUid();
			String username = newChatUserInfo.getUsername();
//			String roomNo = cloudCubeBroadcast.getRoomNo();

			Map<String, NewChatUserInfo> roomUserMap = SessionManager.newGroupId2Users.get(ROOM_NO);
			if(roomUserMap == null) {
				roomUserMap = new ConcurrentHashMap<String, NewChatUserInfo>();
			}

			roomUserMap.put(senderUid, newChatUserInfo);

			SessionManager.newGroupId2Users.put(ROOM_NO, roomUserMap);
			SessionManager.userId2GroupIds.put(senderUid, ROOM_NO);
			log.info("RoomService newJoinCardRoom roomNo:{}, senderUid:{}", ROOM_NO, senderUid);
			//广播加入房间消息
			if(StringUtils.isNotBlank(ROOM_NO) && StringUtils.isNotBlank(senderUid)) {
				ImProto.AddPlayerPack.Builder addPlayerPack = ImProto.AddPlayerPack.newBuilder();
				addPlayerPack.setUsername(username);
				addPlayerPack.setUid(senderUid);

				ImProto.ImMsg.Builder imMsgBuilder = ImProto.ImMsg.newBuilder();
				imMsgBuilder.setMsg(Any.pack(addPlayerPack.build()));
				imMsgBuilder.setId(imMsg.getId());

				log.info("RoomService newJoinCardRoom send start");
				sessionManager.sendMessageToRoomUsers(imMsgBuilder.build(), senderUid);
			}
			// 按照定义的数据结构，创建返回消息对象
			ImProto.AllRoomPlayerResponse.Builder allRoomPlayerResponseBuilder = ImProto.AllRoomPlayerResponse.newBuilder();

			for(NewChatUserInfo roomUser : SessionManager.newGroupId2Users.get(ROOM_NO).values()) {
				if(roomUser.getUid() == null) continue;
				ImProto.UserInfoPack.Builder userInfoPackBuilder = ImProto.UserInfoPack.newBuilder();
				userInfoPackBuilder.setUid(roomUser.getUid());
				userInfoPackBuilder.setUsername(roomUser.getUsername());

				allRoomPlayerResponseBuilder.addUserInfoPack(userInfoPackBuilder);
			}

			ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
			imMsgBuilder.setMsg(Any.pack(allRoomPlayerResponseBuilder.build()));
			imMsgBuilder.setId(imMsg.getId());

			//发送反馈消息
			currSession.sendMessage(imMsgBuilder.build());

		}catch(Exception e) {
			log.error("RoomService newJoinCardRoom error:", e);
			currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户进入房间失败!"));
		}
	}

	public void joinRoom(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			JoinRoomRequest joinRoomRequest = imMsg.getMsg().unpack(JoinRoomRequest.class);
			
			String roomId = joinRoomRequest.getRoomNo();
//			if(SessionManager.groupId2Users == null) {
//				SessionManager.groupId2Users = new ConcurrentHashMap<>();
//			}
			Map<String, ChatUserInfo> roomUserMap = SessionManager.groupId2Users.get(roomId);
			if(roomUserMap == null) {
				roomUserMap = new ConcurrentHashMap<String, ChatUserInfo>();
			}else if(roomUserMap.get(sender_uid) != null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户已在漫游房间中!"));
				return;
			}
			
			//检查人数上限
			String maxUserStr = MessagingConst.globalParams.get(MessagingConst.PARAMKEY_ROOM_MAXUSERS);
			if(StringUtils.isNotBlank(maxUserStr)) {
				if(roomUserMap.size() >= Integer.parseInt(maxUserStr)) {
					currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "超出人数上限."));
					return;
				}
			}
			
			ChatUserInfo userInfo = currSession.getUser();
//			userInfo.setUid(sender_uid);
//			PlayerPack.Builder playerPakBuidler = PlayerPack.newBuilder();
//			playerPakBuidler.setUid(sender_uid);
//			userInfo.setPlayerPack(playerPakBuidler.build());
			roomUserMap.put(userInfo.getUid(), userInfo);
			
			SessionManager.groupId2Users.put(roomId, roomUserMap);
			
			SessionManager.userId2GroupIds.put(sender_uid, roomId);
			
			//广播加入房间消息
			if(userInfo.getPlayerPack() != null) {
				AddPlayer.Builder addPlayerBuilder = AddPlayer.newBuilder();
				addPlayerBuilder.setPlayerPack(userInfo.getPlayerPack());
				ImMsg.Builder imMsgAddPlayerBuilder = ImMsg.newBuilder();
	            
				imMsgAddPlayerBuilder.setMsg(Any.pack(addPlayerBuilder.build()));
				imMsgAddPlayerBuilder.setId(imMsg.getId());
				sessionManager.sendMessageToRoomUsers(imMsgAddPlayerBuilder.build(), sender_uid);
			}
			
	    	// 按照定义的数据结构，创建登录返回消息对象  
			//ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, "Joined success");
			
			
			//返回JoinRoom Response消息
			JoinRoomResponse.Builder joinRoomResponseBuilder = JoinRoomResponse.newBuilder();
			for(ChatUserInfo roomUser : roomUserMap.values()) {
				if(roomUser.getPlayerPack() == null) continue;
				joinRoomResponseBuilder.addPlayerPack(roomUser.getPlayerPack());
			}
    		ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
    		JoinRoomResponse joinRoomResponse = joinRoomResponseBuilder.build();
            
            imMsgBuilder.setMsg(Any.pack(joinRoomResponse));
            imMsgBuilder.setId(imMsg.getId());
            
            //发送反馈消息
	        currSession.sendMessage(imMsgBuilder.build());
	        
		}catch(Exception e) {
			log.error("Join Room时发生异常, ", e);
		}
		
	}
	/**
	 * 离开房间
	 * @param imMsg
	 * @param currSession
	 */
	public void newExitRoom(ImProto.ImMsg imMsg, IoSession currSession) {
		try {
			ImProto.CloudCubeBroadcast cloudCubeBroadcast = imMsg.getMsg().unpack(ImProto.CloudCubeBroadcast.class);
			NewChatUserInfo newChatUserInfo = currSession.getNewChatUserInfo();
			if (Objects.isNull(newChatUserInfo) || StringUtils.isBlank(newChatUserInfo.getUid())){
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "无法找到用户信息!"));
				return;
			}
//			String roomNo = cloudCubeBroadcast.getRoomNo();
			String roomNo = "chimeta";

			newProcessExitRoom(newChatUserInfo.getUid(), roomNo);
			ImProto.ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, "Exit success");
			//发送反馈消息
			currSession.sendMessage(responseMsg);
		} catch (InvalidProtocolBufferException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 操作离开房间
	 * @param uid
	 * @param roomId
	 */
	public void newProcessExitRoom(String uid, String roomId) {
		Map<String, NewChatUserInfo> roomUserSet = SessionManager.newGroupId2Users.get(roomId);
		if(roomUserSet != null && roomUserSet.get(uid) != null) {
			//广播退出房间消息
			if(roomUserSet.get(uid) != null) {
				ImProto.ExitRoomPack.Builder exitRoomBuilder = ImProto.ExitRoomPack.newBuilder();
				exitRoomBuilder.setUid(uid);
				exitRoomBuilder.setUsername(roomUserSet.get(uid).getUsername());
				ImProto.ImMsg.Builder imMsgExitRoomBuilder = ImProto.ImMsg.newBuilder();
				imMsgExitRoomBuilder.setMsg(Any.pack(exitRoomBuilder.build()));
				sessionManager.sendMessageToAllRoomUsers(imMsgExitRoomBuilder.build(), uid);
			}

			roomUserSet.remove(uid);
			SessionManager.newGroupId2Users.put(roomId, roomUserSet);
		}

		SessionManager.userId2GroupIds.remove(uid);
	}

	public void exitRoom(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getNewUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getNewChatUserInfo().getUid();
			
			if(SessionManager.newGroupId2Users == null) {
				SessionManager.newGroupId2Users = new ConcurrentHashMap<>();
			}
			
			String roomId = SessionManager.userId2GroupIds.get(sender_uid);
			if(StringUtils.isBlank(roomId)) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "User not in any room."));
				return;
			}
			
//			Map<String, ChatUserInfo> roomUserSet = sessionManager.groupId2Users.get(roomId);
//			if(roomUserSet != null) {
//				roomUserSet.remove(sender_uid);
//				if(roomUserSet== null || roomUserSet.isEmpty()) {
//					//销魂房间数据
//					sessionManager.groupId2Users.remove(roomId);
//				}
//				
//				//广播退出房间消息
//				Logout.Builder logoutBuilder = Logout.newBuilder();
//				logoutBuilder.setPlayerPack(roomUserSet.get(sender_uid).getPlayerPack());
//				ImMsg.Builder imMsgLogoutrBuilder = ImMsg.newBuilder();
//	            
//				imMsgLogoutrBuilder.setMsg(Any.pack(logoutBuilder.build()));
//				imMsgLogoutrBuilder.setId(imMsg.getId());
//				sessionManager.sendMessageToRoomUsers(imMsgLogoutrBuilder.build(), sender_uid);
//			}
			processExitRoom(sender_uid, roomId);
			
	    	// 按照定义的数据结构，创建登录返回消息对象  
			ImMsg responseMsg = MessageBuilder.buildSuccessResponse(imMsg, "Exit success");
	        //发送反馈消息
	        currSession.sendMessage(responseMsg);
	        
		}catch(Exception e) {
			log.error("Exit Room时发生异常, ", e);
		}
		
	}
	
	public void processExitRoom(String uid, String roomId) {
		Map<String, NewChatUserInfo> roomUserSet = SessionManager.newGroupId2Users.get(roomId);
		if(roomUserSet != null && roomUserSet.get(uid) != null) {
			//广播退出房间消息 todo要做的
//			if(roomUserSet.get(uid).get() != null) {
//				ExitRoom.Builder exitRoomBuilder = ExitRoom.newBuilder();
//				exitRoomBuilder.setPlayerPack(roomUserSet.get(uid).getPlayerPack());
//				ImMsg.Builder imMsgExitRoomBuilder = ImMsg.newBuilder();
//
//				imMsgExitRoomBuilder.setMsg(Any.pack(exitRoomBuilder.build()));
//				//imMsgLogoutrBuilder.setId(imMsg.getId());
//				sessionManager.sendMessageToAllRoomUsers(imMsgExitRoomBuilder.build(), uid);
//			}
			
			roomUserSet.remove(uid);
			if(roomUserSet== null || roomUserSet.isEmpty()) {
				//销魂房间数据
				SessionManager.newGroupId2Users.remove(roomId);
			}
		}
		
		SessionManager.userId2GroupIds.remove(uid);
	}
	
	
	public void updateUser(ImMsg imMsg, IoSession currSession) {
		
		try {
			if(currSession.getUser() == null) {
				currSession.sendMessage(MessageBuilder.buildErrorResponse(imMsg, MessagingConst.RESPONSE_ERR_CODE_400, "用户未登录!"));
				return;
			}
			String sender_uid = currSession.getUser().getUid();
			UpPos upPosRequest = imMsg.getMsg().unpack(UpPos.class);
			PlayerPack upPack = upPosRequest.getPlayerPack();
			if(upPack == null) {
				return;
			}
			currSession.getUser().setPlayerPack(upPack);
			
			String room_id = SessionManager.userId2GroupIds.get(sender_uid);
			//如果在漫游房间
			if(StringUtils.isNotBlank(room_id) && SessionManager.groupId2Users.get(room_id) != null) {
				
				//SessionManager.groupId2Users.get(room_id).get(sender_uid).setPlayerPack(upPack);
				//广播UpPos消息
				sessionManager.sendMessageToRoomUsers(imMsg, sender_uid);
			}
			
			//如果在演练房间
			LobbyRoomInfo lobbyRoomInfo = SessionManager.userId2LobbyRooms.get(sender_uid);
			if(lobbyRoomInfo != null) {

				//广播UpPos消息
				sessionManager.sendMessageToLobbyRoomPlayers(imMsg, sender_uid, false);
			}
			
			
			//返回UpPos Response消息
    		ImMsg.Builder imMsgBuilder = ImMsg.newBuilder();
    		UpPosResponse.Builder upPosResponseBuidler = UpPosResponse.newBuilder();
    		UpPosResponse upPosResponse = upPosResponseBuidler.build();
            imMsgBuilder.setMsg(Any.pack(upPosResponse));
            imMsgBuilder.setId(imMsg.getId());
            
            //发送反馈消息
	        currSession.sendMessage(imMsgBuilder.build());
	        
		}catch(Exception e) {
			log.error("Update Pos时发生异常, ", e);
		}
		
	}
	
	
}
